package com.zbkj.client.controller;

import com.zbkj.client.config.ClientTokenComponent;
import com.zbkj.client.config.SSESessionManager;
import com.zbkj.common.result.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * SSE控制器
 * 用于处理SSE连接请求和消息发送
 */
@Slf4j
@RestController
@RequestMapping("/api/client/sse")
public class SSEController {

    @Autowired
    private SSESessionManager sseSessionManager;

    @Autowired
    private ClientTokenComponent clientTokenComponent;

    /**
     * 建立SSE连接
     * @param request HTTP请求
     * @return SSE发射器
     */
    @GetMapping(value = "/connect")
    public CommonResult<Map<String, String>> connect(HttpServletRequest request) {

        Integer userId = clientTokenComponent.getLoginUser(request);
        if (userId == null) {
            return CommonResult.failed("用户未登录");
        }

        // 创建SSE发射器，设置超时时间为30分钟
        SseEmitter emitter = new SseEmitter(1800000L); // 30分钟 = 1800000毫秒

        // 注册SSE会话
        String sessionId = sseSessionManager.registerSession(userId, emitter);
        log.info("SSE连接已建立，用户ID: {}, 会话ID: {}", userId, sessionId);

        Map<String, String> map = new HashMap<>();
        map.put("sessionId", sessionId);

        return CommonResult.success(map);
    }

    /**
     * 获取SSE会话ID（用于建立连接前的准备）
     * @param request HTTP请求
     * @return 会话ID
     */
    @GetMapping(value = "/get-session-id")
    public CommonResult<Map<String, String>> getSessionId(HttpServletRequest request) {

        Integer userId = clientTokenComponent.getLoginUser(request);
        if (userId == null) {
            return CommonResult.failed("用户未登录");
        }

        // 生成一个临时的会话ID，用于后续建立连接
        String sessionId = java.util.UUID.randomUUID().toString();
        log.info("生成SSE会话ID，用户ID: {}, 会话ID: {}", userId, sessionId);
        
        Map<String, String> map = new HashMap<>();
        map.put("sessionId", sessionId);

        return CommonResult.success(map);
    }

    /**
     * 发送消息到指定用户
     * @param userId 用户ID
     * @param eventName 事件名称
     * @param data 消息数据
     * @return 操作结果
     */
    @PostMapping("/send/{userId}")
    public CommonResult<String> sendMessage(
            @PathVariable Integer userId,
            @RequestParam String eventName,
            @RequestBody Object data) {
        try {
            sseSessionManager.sendMessageToUser(userId, eventName, data);
            return CommonResult.success("消息发送成功");
        } catch (Exception e) {
            log.error("发送消息失败，用户ID: {}, 事件: {}, 错误: {}", userId, eventName, e.getMessage());
            return CommonResult.failed("发送消息失败: " + e.getMessage());
        }
    }

    /**
     * 发送消息到所有用户（广播）
     * @param eventName 事件名称
     * @param data 消息数据
     * @return 操作结果
     */
    @PostMapping("/broadcast")
    public CommonResult<String> broadcastMessage(
            @RequestParam String eventName,
            @RequestBody Object data) {
        try {
            // 获取所有用户ID并发送消息
            sseSessionManager.broadcastMessage(eventName, data);
            return CommonResult.success("广播消息发送成功");
        } catch (Exception e) {
            log.error("广播消息失败，事件: {}, 错误: {}", eventName, e.getMessage());
            return CommonResult.failed("广播消息失败: " + e.getMessage());
        }
    }

    /**
     * 心跳接口，用于保持SSE连接活跃
     * @param sessionId 会话ID
     * @return 操作结果
     */
    @GetMapping("/heartbeat/{sessionId}")
    public CommonResult<String> heartbeat(@PathVariable String sessionId) {
        try {
            sseSessionManager.refreshSession(sessionId);
            return CommonResult.success("心跳成功");
        } catch (Exception e) {
            log.error("心跳失败，会话ID: {}, 错误: {}", sessionId, e.getMessage());
            return CommonResult.failed("心跳失败: " + e.getMessage());
        }
    }

    /**
     * 关闭SSE连接
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return 操作结果
     */
    @DeleteMapping("/close/{userId}/{sessionId}")
    public CommonResult<String> closeConnection(
            @PathVariable Integer userId,
            @PathVariable String sessionId) {
        try {
            sseSessionManager.removeSession(userId, sessionId);
            return CommonResult.success("连接已关闭");
        } catch (Exception e) {
            log.error("关闭连接失败，用户ID: {}, 会话ID: {}, 错误: {}", userId, sessionId, e.getMessage());
            return CommonResult.failed("关闭连接失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户连接状态
     * @param userId 用户ID
     * @return 连接状态
     */
    @GetMapping("/status/{userId}")
    public CommonResult<Map<String, Object>> getUserStatus(@PathVariable Integer userId) {
        try {
            boolean hasActiveSession = sseSessionManager.hasActiveSession(userId);
            int sessionCount = sseSessionManager.getUserSessionIds(userId).size();
            
            Map<String, Object> status = new ConcurrentHashMap<>();
            status.put("userId", userId);
            status.put("hasActiveSession", hasActiveSession);
            status.put("sessionCount", sessionCount);
            status.put("timestamp", System.currentTimeMillis());
            
            return CommonResult.success(status);
        } catch (Exception e) {
            log.error("获取用户状态失败，用户ID: {}, 错误: {}", userId, e.getMessage());
            return CommonResult.failed("获取用户状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统统计信息
     * @return 统计信息
     */
    @GetMapping("/stats")
    public CommonResult<Map<String, Object>> getStats() {
        try {
            int activeSessionCount = sseSessionManager.getActiveSessionCount();
            
            Map<String, Object> stats = new ConcurrentHashMap<>();
            stats.put("activeSessionCount", activeSessionCount);
            stats.put("timestamp", System.currentTimeMillis());
            
            return CommonResult.success(stats);
        } catch (Exception e) {
            log.error("获取统计信息失败，错误: {}", e.getMessage());
            return CommonResult.failed("获取统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 测试SSE连接
     * @param sessionId 会话ID
     * @return 操作结果
     */
    @PostMapping("/test/{sessionId}")
    public CommonResult<String> testConnection(@PathVariable String sessionId) {
        try {
            // 构造测试消息
            Map<String, Object> testData = new HashMap<>();
            testData.put("message", "这是一条测试消息");
            testData.put("timestamp", System.currentTimeMillis());
            testData.put("sessionId", sessionId);
            
            String testMessage = "data: " + com.alibaba.fastjson.JSON.toJSONString(testData) + "\n\n";
            
            boolean success = sseSessionManager.sendRawToSession(sessionId, testMessage);
            
            if (success) {
                return CommonResult.success("测试消息发送成功");
            } else {
                return CommonResult.failed("测试消息发送失败，会话可能不存在或已失效");
            }
        } catch (Exception e) {
            log.error("测试SSE连接失败，会话ID: {}, 错误: {}", sessionId, e.getMessage());
            return CommonResult.failed("测试失败: " + e.getMessage());
        }
    }
} 